package com.common.www.filter;

import com.alibaba.fastjson.JSON;
import com.common.www.bean.entity.Result;
import com.common.www.utils.R;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@ControllerAdvice
public class HttpGlobalExceptionHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpGlobalExceptionHandler.class);
    private static String key = "com.bianmaba.real_estate_app";

    public HttpGlobalExceptionHandler() {
    }

    @ExceptionHandler({Exception.class, RuntimeException.class})
    public void handleException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
//        String tackStr = getStackTraceString(e.getStackTrace()).toString();
        Result result = R.fail(e.toString() + "");
        writeJson(response, result, 200);
        LOGGER.error("资源请求失败，请求的资源出现异常！", e);
    }

    @ExceptionHandler({NullPointerException.class})
    public void handleNullPointerException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
        Result result = R.fail("空指针异常" + "");
        writeJson(response, result, 200);
        LOGGER.error("资源请求失败，请求的资源出现异常！", e);
    }

    @ExceptionHandler({JpaSystemException.class})
    public void handleJpaSystemException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
        Result result = R.fail("JPA查询失败" + "");
        writeJson(response, result, 200);
        LOGGER.error("资源请求失败，请求的资源出现异常！", e);
    }

    @ExceptionHandler({IllegalArgumentException.class})
    public void handleIllegalArgumentException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
        Result result = R.fail("参数异常,格式不匹配" + "");
        writeJson(response, result, 200);
        LOGGER.error("资源请求失败，请求的资源出现异常！", e);
    }

    @ExceptionHandler({NumberFormatException.class})
    public void handleNumberFormatException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
        Result result = R.fail(e.toString() + "");
        writeJson(response, result, 200);
        LOGGER.error("资源请求失败，请求的资源出现异常！", e);
    }


    /**
     * 获取错误的堆栈信息
     *
     * @param throwable
     * @return
     */
    public String getStackTrace(Throwable throwable) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);

        try {
            throwable.printStackTrace(printWriter);
            return stringWriter.toString();
        } finally {
            printWriter.close();
        }

    }


    /**
     * 递归错误文本
     */
    private StringBuilder getStackTraceString(StackTraceElement[] elements) {
        StringBuilder builder = new StringBuilder();
        if (elements == null)
            return builder.append("获取错误失败");
        for (int i = 0; i < elements.length; i++) {
            builder.append(elements[i].toString());
            builder.append("\n");
        }
        return builder;
    }

    public static void writeJson(HttpServletResponse response, Object data, Integer status) throws IOException {
        String json = null;

        try {
            response.setStatus(status);
            response.setContentType("application/x-json;charset=UTF-8");
//            json = JSONUtil.serialize(data);
            json = JSON.toJSONString(data);
        } catch (Exception var5) {
            LOGGER.error("JSON对象序列化出现异常。", var5);
        }

        response.getOutputStream().write(json.getBytes("UTF-8"));
        response.getOutputStream().flush();
    }
}
